require "Common/define"
require "Logic/Config"
require "Common/functions"
---@class SkillManager
SkillManager = {};
local this = SkillManager;
local skillInfoConfig = nil;
local skillConfig = nil;
local skillShowConfig = nil;
local heroConfig = nil;
local heroRankConfig = nil;
local supSkillConfig = nil;
local supSkillInfo = nil;
local allSkillData = nil;
local allSkill = nil;
local formationType2SkillId = {};--{[队伍类型] = 援助技能id
local formationTypePetSkillId = nil
local supSkillLv = 1;--援助技能总等级

function SkillManager.init()
    skillInfoConfig = G.dataTable["t_skillinfo"];
    skillConfig = G.dataTable["t_skill"];
    skillShowConfig = G.dataTable["t_skillshow"];
    heroConfig = G.dataTable["t_hero"];
    heroRankConfig = G.dataTable["t_herorank"];
    allSkill = G.dataTable["t_assistantskill"];
    supSkillConfig = {};
    supSkillInfo = {};
    if #supSkillConfig == 0 then
        for k, v in pairs(allSkill) do
            v.f_Cost = decodeJsonStrToTabel(v.f_Cost);
            v.f_GetCondition = decodeJsonStrToTabel(v.f_GetCondition);
            if supSkillConfig[v.f_AssistantSkillGroup] == nil then
                supSkillConfig[v.f_AssistantSkillGroup] = {};
            end
            table.insert(supSkillConfig[v.f_AssistantSkillGroup], v);
            table.sort(supSkillConfig[v.f_AssistantSkillGroup], function(a, b)
                return a.f_Level < b.f_Level
            end)
        end
    end
end

function SkillManager.getSupSkillConfig()
    return supSkillConfig;
end

function SkillManager.setSupSkillInfo(msg)
    supSkillInfo = msg.skillList;
    if table.getn(supSkillInfo) >= 1 then
        this.supSkillLv = supSkillInfo[1].skillLev;
    end

    for k, v in pairs(supSkillInfo) do
        for type, skillId in pairs(formationType2SkillId) do
            if allSkill[tostring(v.skillId)].f_AssistantSkillGroup == allSkill[tostring(skillId)].f_AssistantSkillGroup then
                formationType2SkillId[type] = v.skillId;
            end
        end
    end
    logicMgr.TATrackCollect.Track_SupSkill()
end

function SkillManager.getSupFullLevelSkillInfo()
    local data = {};
    for k, v in pairs(supSkillInfo) do
        local item = {};
        item.isUse = v.isUse;
        item.skillLev = 25
        item.skillId = supSkillConfig[allSkill[tostring(v.skillId)].f_AssistantSkillGroup][item.skillLev].f_AssistantSkillId;
        item.skillOldId = v.skillId;
        table.insert(data, item);
    end
    return data;
end

function SkillManager.getSupSkillInfo()
    return supSkillInfo;
end

function SkillManager.setSupSkillSrverData(msg)
    for k, v in pairs(supSkillInfo) do
        if allSkill[tostring(v.skillId)].f_AssistantSkillGroup == allSkill[tostring(msg.skillId)].f_AssistantSkillGroup then
            this.supSkillLv = msg.skillLev;
            v.skillId = msg.skillId;
            for type, skillId in pairs(formationType2SkillId) do
                if allSkill[tostring(msg.skillId)].f_AssistantSkillGroup == allSkill[tostring(skillId)].f_AssistantSkillGroup then
                    formationType2SkillId[type] = msg.skillId;
                end
            end
            --援护技能升级埋点
            local _supportSkillDic = {}
            _supportSkillDic.assistant_level = tonumber(msg.skillLev)
            _supportSkillDic.assistant_skill_id = tostring(msg.skillId)
            _supportSkillDic.assistant_skill_group = allSkill[tostring(msg.skillId)].f_AssistantSkillGroup
            TAManager.TrackByDictionary("assistant_skill_levelup", _supportSkillDic)
            break ;
        end
    end
end

function SkillManager.getImitationSkillInfos(skillField)
    --获取可模仿的技能
    local list = {};
    if skillField == EnumConst.SkillFieldType.SpecialTwo or skillField == EnumConst.SkillFieldType.Passive then
        local heroInfos = logicMgr.HeroManager.getOwnerHeroList(false);
        local selfInfo = logicMgr.HeroManager.getMyself();
        local curSkillInfo = this.getSkillInfosById(selfInfo.partnerModelId)[skillField];
        table.insert(heroInfos, 1, selfInfo);
        for i = 1, #heroInfos do
            if heroInfos[i].star >= G.dataTable["t_global"]["51"].f_int_value and heroInfos[i].type == selfInfo.type then
                local heroItemConfig = heroConfig[tostring(heroInfos[i].partnerModelId)];
                if heroItemConfig ~= nil and curSkillInfo.f_SkillID ~= heroItemConfig["f_HeroSkill" .. skillField] then
                    local skillInfo = skillInfoConfig[tostring(heroItemConfig["f_HeroSkill" .. skillField])];
                    if skillInfo ~= nil and this.getSkillLv(skillInfo, selfInfo.level) > 0 then
                        local data = { skill = skillInfo, hero = heroInfos[i] };
                        table.insert(list, data);
                    end
                end
            end
        end
    end

    return list;
end

function SkillManager.getSkillInfosById(partnerModelId)
    --获得当前英雄的技能的skillInfo列表
    local list = {};
    local hero = logicMgr.HeroManager.getHeroDatabyModelId(partnerModelId, true);
    if hero == nil then
        return list;
    end
    local heroCg = heroConfig[tostring(hero.partnerModelId)];
    local heroSkills = hero["skillIds"];
    for i = 1, 5 do
        local skillInfo = nil;
        if heroSkills ~= nil then
            for k, v in pairs(heroSkills) do
                if this.getSkilField(v) == i then
                    skillInfo = this.getSkillInfoConfig(v);
                    break ;
                end
            end
        end
        local id = heroCg["f_HeroSkill" .. i]
        if skillInfo == nil then
            skillInfo = skillInfoConfig[tostring(id)];
        end
        if skillInfo then
            table.insert(list, skillInfo);
        else
            if id > 0 then
                logError("t_skillinfo 找不到技能 " .. id)
            end
        end
    end
    return list;
end

function SkillManager.getSkillInfosByModelId(partnerModelId)
    --t_hero中配的的SkillInfo
    local list = {};
    local heroCg = heroConfig[tostring(partnerModelId)];
    if heroCg ~= nil then
        for i = 1, 5 do
            local skillInfoId = heroCg["f_HeroSkill" .. i];
            if skillInfoId ~= nil and skillInfoId > 0 then
                local info = skillInfoConfig[tostring(skillInfoId)]
                if info then
                    table.insert(list, info);
                else
                    logError("t_skillInfo 找不到技能 " .. skillInfoId)
                end

            end
        end
    end
    return list;
end

function SkillManager.getRealSkills(partnerId)
    --获取英雄战斗所用的真正的技能id
    local list = {};
    local hero = logicMgr.HeroManager.getHeroDatabyPartnerId(partnerId, true);
    if hero ~= nil then
        local rankId = hero.partnerModelId * 100000 + hero.star;
        local rankConfig = heroConfig[tostring(rankId)];
        if rankConfig ~= nil then
            for i = 1, 4 do
                local skillId = rankConfig["f_Skill" .. i];
                if skillId ~= nil then
                    table.insert(list, skillId);
                end
            end
        end
        local skillIds = hero.skillIds;
        if skillIds ~= nil then
            for i = 1, #skillIds do
                local isDeal = false;
                for j = 1, #list do
                    if this.getSkilField(skillIds[i]) == this.getSkilField(list[j]) then
                        list[j] = skillIds[i];
                        isDeal = true;
                        break ;
                    end
                end
                if isDeal == false then
                    table.insert(list, skillIds[i]);
                end
            end
        end
    end
    return list;
end

function SkillManager.getSkilField(skillId)
    -- -- 根据skilId获得技能栏位ID
    return Mathf.Floor(skillId % 10000 / 1000) - 1;
end

function SkillManager.getSkillInfoConfig(skillId)
    -- 根据skilId获得skillInfo配置
    local skillInfoId = Mathf.Floor(skillId / 1000) * 1000 + 100;
    return skillInfoConfig[tostring(skillInfoId)], skillInfoId;
end

function SkillManager.getSkillLv(skillInfo, level, quality)
    --星级对应的技能等级
    local starArray = (skillInfo.f_SkillList);
    local lv = 0
    for i = 1, #starArray do
        local data = G.dataTable["t_skillunlocker"][tostring(starArray[i])]
        if data then
            local limitLv = data.f_SkillUnlocker
            local limitQuality = data.f_SkillRelease
            local qFlag = (quality == nil) or (quality and limitQuality and limitQuality / 10 <= quality)
            if limitLv <= level and qFlag then
                lv = i;
            else
                break ;
            end
        end
    end
    return lv;
end

function SkillManager.getRealSkillByLv(skillInfo, lv)
    -- 获取t_skill的配置
    if lv <= 0 then
        return nil;
    end
    local skillIds = decodeJsonStrToTabel(skillInfo.f_SkillList);
    local skillId = skillIds[lv];
    if skillId == nil then
        return nil;
    end
    return skillConfig[tostring(skillId)];
end

function SkillManager.getRealSkillByStar(skillInfo, star)
    -- 获取t_skill的配置
    local lv = this.getSkillLv(skillInfo, star);
    return this.getRealSkillByLv(skillInfo, lv);
end

function SkillManager.getSkillShow(skillId)
    return skillShowConfig[tostring(skillId)];
end

function SkillManager.selectSupSkill(id)
    --if id ~= nil and id ~= 0 then
    --    for i = 1, #supSkillInfo do
    --        if allSkill[tostring(supSkillInfo[i].skillId)].f_AssistantSkillGroup == allSkill[tostring(id)].f_AssistantSkillGroup then
    --            supSkillInfo[i].isUse = 1;
    --        else
    --            supSkillInfo[i].isUse = 0;
    --        end
    --    end
    FireEvent(Config.EventType.AssistantSkill);
    --end
end
--重置援助技
function SkillManager.setSupSkillReset(id)
    if id ~= 0 then
        for i = 1, #supSkillInfo do
            if supSkillInfo[i].skillId == id then
                local groupId = G.dataTable["t_assistantskill"][tostring(id)].f_AssistantSkillGroup;
                supSkillInfo[i].skillId = supSkillConfig[groupId][1].f_AssistantSkillId;
                this.supSkillLv = 1;
            end
        end
        FireEvent(Config.EventType.Fresh_AssistantSkillReset);
    end
end
function SkillManager.GetSelectSkillId()
    local supSkills = this.getSupSkillInfo()
    for i = 1, #supSkills do
        if supSkills[i].isUse == 1 then
            local id = supSkills[i].skillId;
            return id
        end
    end
    return 0
end

function SkillManager.initFormationAssistantSkillList(formationType, skillId)
    if formationType2SkillId == nil then
        formationType2SkillId = {};
    end

    formationType2SkillId[tonumber(formationType)] = skillId;
end

function SkillManager.initFormationPetSkillList(formationType, skillId)
    if formationTypePetSkillId == nil then
        formationTypePetSkillId = {};
    end

    formationTypePetSkillId[formationType] = skillId;
end

function SkillManager.getPetSkillIdByFormationType(formationType)
    --[[if formationType == EnumConst.FormationType.FormationEditor then
        local index = FormationManager.GetFocus()
        formationType = formationType + index
    end--]]
    return (formationTypePetSkillId and formationTypePetSkillId[formationType]) and formationTypePetSkillId[formationType] or 0
end


function SkillManager.getSupSkillIdByFormationType(formationType)
    if formationType == nil then
        return formationType2SkillId;
    end
    formationType = tonumber(formationType)
    if formationType == EnumConst.FormationType.FormationEditor then
        local index = FormationManager.GetFocus()
        formationType = formationType + index
    end

    return formationType2SkillId[formationType];
end

function SkillManager.GetSkillInfoByID(sk_id)
    if supSkillInfo then
        for k, v in pairs(supSkillInfo) do
            if v.skillId == sk_id then
                return v
            end
        end
    end
    return nil
end

--检查是否是公用技能
function SkillManager.checkSkillSkin(skillId)
    if EnumConst.publicSkillRes[skillId] then
        return true;
    end
    return false;
end

function SkillManager.checkHitSkin(buffRes)
    if EnumConst.publicHitRes[buffRes] then
        return true;
    end
    return false;
end
function SkillManager.checkBuffSkin(buffRes)
    if EnumConst.publicBuffRes[buffRes] then
        return true;
    end
    return false;
end
function SkillManager.checkBulletSkin(bulletRes)
    if EnumConst.publicBulletRes[bulletRes] then
        return true;
    end
    return false;
end
function SkillManager.checkIsOut(skillId)
    local skillInfo = G.dataTable["t_skill"][tostring(skillId)];
    if skillInfo then
       return skillInfo.f_SkillOut == 1;
    end
end

function SkillManager.getNeedChooseHeroById(partnerModelId, level, quality)
    if partnerModelId == nil or level == nil or quality == nil then
        return ;
    end
    this.cacheNeedChooseHeroList = this.cacheNeedChooseHeroList or {}
    this._key = string.format("%s_%s_%s", partnerModelId, level, quality);
    if this.cacheNeedChooseHeroList[this._key] then
        if this.cacheNeedChooseHeroList[this._key] == "nil" then
            return;
        else
            return this.cacheNeedChooseHeroList[this._key];
        end
    end
    this.cacheNeedChooseHeroList[this._key] = {};
    local skillInfos = logicMgr.SkillManager.getSkillInfosById(partnerModelId);
    for k, v in pairs(skillInfos) do
        local skillData = logicMgr.SkillManager.getRealSkillByLv(v, logicMgr.SkillManager.getSkillLv(v, level, quality));
        if skillData and skillData.f_conditionType ~= 0 then
            skillData._skillIndex = k;
            table.insert(this.cacheNeedChooseHeroList[this._key], skillData);
        end
    end
    if #this.cacheNeedChooseHeroList[this._key] > 0 then
        return this.cacheNeedChooseHeroList[this._key];
    end
    this.cacheNeedChooseHeroList[this._key] = "nil";
end
--战力技能加成
function SkillManager.SkillAddPower(partnerModelId,level, quality)
    local skillInfos = logicMgr.SkillManager.getSkillInfosById(partnerModelId);
    local addNum = 0
    for k, v in pairs(skillInfos) do
        local starArray = (v.f_SkillList);
        for i = #starArray,1,-1  do
            local data = dataTable.getDataTableByStringId("t_skillunlocker",tostring(starArray[i]))
            if data then
                local limitLv = data.f_SkillUnlocker
                local limitQuality = data.f_SkillRelease
                local qFlag = (quality == nil) or (quality and limitQuality and limitQuality / 10 <= quality)
                if limitLv <= level and qFlag then
                    addNum = addNum + data.f_SkillIPower / 10000
                    break
                end
            end
        end
    end
    return addNum
end
return SkillManager